import SerialPort from 'serialport'
import { Context } from 'koa';
const cp = require('child_process').execFile
import { logger } from "../until/log"
import websocketIo from "../until/websocket.io";
import eventEmit from "../until/emitEvent";
import AdminService from '../service/admin.service'
// import testClass from "./testClass";
import config from '../../config'
interface IData {
  ID: number;
  data: number[];
  sta: number[];
}
class SocketController {
    public serialName;
    static serialport:SerialPort;
    public baudRate:number; // 波特率
    static localData:any;
    static isOpenSerial:boolean = false; // 是否打开了串口
    static receiveTime = new Date().getTime(); // 获取接收的时间戳
    static timer:any;
    //重写报警逻辑
    public catchError(data: IData):IData {
        let catch_uv = eventEmit.settingData[data.ID - 1][0].current_val // 紫外报警阈值
        let catch_ir = eventEmit.settingData[data.ID - 1][1].current_val // 红外报警阈值
        let catch_temp = eventEmit.settingData[data.ID - 1][2].current_val // 温度报警阈值
        let catch_hum = eventEmit.settingData[data.ID - 1][3].current_val // 湿度报警阈值
        let catch_pre = eventEmit.settingData[data.ID - 1][4].current_val // 压力报警阈值
        let catch_param = [catch_uv, catch_ir, catch_temp, catch_hum, catch_pre]
        let new_sta: number[] = data.data.map((item: any,index: number) => {
            if (item > catch_param[index]) {
                return 1
            } else {
                return 0
            }
        } )
        return {
            ID: data.ID,
            data: data.data,
            sta: new_sta
        }
    }
    // 连接串口
    connectionSerialport(serialName,baudRate:number,parity) {
        this.baudRate = baudRate
        this.serialName = serialName
        // @ts-ignore
        SocketController.serialport = new SerialPort(this.serialName,{baudRate: this.baudRate,dataBits:8,parity},(err) => {
            if (err) return console.log("打开串口失败" + err)
                console.log(`打开${this.serialName}串口成功!!!`)
                // setTimeout(() => {
                //     cp('app.exe',(err) => {
                //         if (err) {
                //             console.log("项目启动失败，重新尝试！！！")
                //             logger.error("项目启动失败，重新尝试" + err)
                //         }
                //     })
                // },200)
            // testClass.startWhile()
            SocketController.isOpenSerial = true
            const parser = SocketController.serialport.pipe(new SerialPort.parsers.Delimiter({ delimiter: "}"}))
            parser.on("data", async chunk => {
                if(chunk.includes("NUM")) {
                    setTimeout(() => {
                        SocketController.serialport.write('NUM=' + eventEmit.moduleNum)
                    },100)
                } else if(chunk.includes("FLASHOK")) {
                    console.log("%c FLASH OK","color: red;background:#ccc")
                } else if(chunk.includes("RAMOK")) {
                    console.log("%c RAM OK","color: red;background: #ccc")
                } else {
                    SocketController.receiveTime = new Date().getTime() // 记录接收的时间
                    let str = chunk.toString()+"]}"
                    str = str.replace(/\*/g,"")
                    try {
                        // 把数据传递给前端
                        let data = JSON.parse(str)
                        data = this.catchError(data)
                        await AdminService.saveDataList({
                            module_id: data.ID,
                            uvc: data.data[0],
                            inf: data.data[1],
                            tem: data.data[2],
                            hum: data.data[3],
                            pre: data.data[4]
                        })
                        await AdminService.saveStatusList({
                            module_id: data.ID,
                            uvc_sta: data.sta[0],
                            ir_sta: data.sta[1],
                            temp_sta: data.sta[2],
                            hum_sta: data.sta[3],
                            pre_sta: data.sta[4]
                        })
                        if (websocketIo.getInstance.socketObj) websocketIo.getInstance.socketObj.send(JSON.stringify({...data,action: 'sendData'}))
                    } catch (err) {
                        logger.error("传输的数据格式有问题：" + err + "格式为：" + str)
                    }
                }
            })
        })
    }
    static isSend() {
     return new Promise((resolve => {
         let sendTime = new Date().getTime()  // 获取发送的时间
         let spaceTime = sendTime - SocketController.receiveTime // 获取发送和接收的时间间隔
         if (spaceTime > 200 && spaceTime < 800) {
              resolve(true)
         } else {
             console.log("相撞了")
              resolve(false)
         }
     }))
    }
    // 获取串口数据
    getSerialPort(ctx:Context){
        if (SocketController.isOpenSerial) {
            ctx.body = {
                code: 200,
                msg: "获取串口数据成功",
                data: SocketController.localData
               }
        } else {
            ctx.body = {
                code: 304,
                msg: "还没有打开串口"
            }
        }
    }
    async changeSerialPort(ctx:any) {
        let varNameList = ['uv','inf',"acc",'tem','hum','pre'] // 定义一个变量的数组
        let id = ctx.request.body.id
        let device_id = ctx.request.body.device_id // 设备的id
        let alarm = ctx.request.body.currentValue
         let obj = {
             ID: device_id,
             [varNameList[id - 1]]: {alarm:[alarm]}
         }
         console.log(JSON.stringify(obj).trim())
        try {
           let bool = await SocketController.isSend()
            if (bool) {
                let bool = await SocketController.serialport.write(JSON.stringify(obj).trim())
            } else {
                setTimeout(() => {
                    SocketController.serialport.write(JSON.stringify(obj).trim(),(err) => {
                        if (err) return console.log("写入失败")
                    })
                },200)
            }
        } catch(err) {
            logger.error("修改阈值失败" + err)
            ctx.body = {code: 500,msg:"修改阈值失败，查看设备连接"}
        }
            ctx.body = {
                code: 200,
                msg: "修改成功",
                data: obj
            }
    }
    async changeSpeed(ctx:any) {
        // 改变数据采样的速率
        let bool = await SocketController.isSend()
        let speed = ctx.request.body.speed
        if (bool) {
            await SocketController.serialport.write(`{DELAY:[${speed}]}`,(err) => {
                if (err) return ctx.body = {code: 500,msg: "修改失败"}
            })
            ctx.body = {code: 200,msg: "修改速率成功"}
        } else {
            setTimeout(() => {
                SocketController.serialport.write(`{DELAY:[${speed}]}`,(err) => {
                    if (err) return ctx.body = {code: 500,msg: "修改失败"}
                })
            },200)
            ctx.body = {code: 200,msg: "修改速率成功"}
        }
    }
    // 获取模块的个数
    async getModuleNum(ctx:Context) {
        ctx.body = {
            code: 200,
            msg: "获取模块的个数成功",
            data: {
                moduleNum: eventEmit.moduleNum,
                uv: config.uv,
                inf: config.inf,
                other: config.other
            }
        }
    }
}

export default new SocketController
